<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="chrome=1">
    <title>Marlin by atmb4u</title>
    <link rel="stylesheet" href="https://rawgithub.com/atmb4u/marlin/master/marlin/static/stylesheets/styles.css">
    <link rel="stylesheet" href="https://rawgithub.com/atmb4u/marlin/master/marlin/static/stylesheets/pygment_trac.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script src="https://rawgithub.com/atmb4u/marlin/master/marlin/static/javascripts/main.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

  </head>
  <body>

      <header>
        <h1>Marlin</h1>
        <p>Fast and easy ReST API server on redis</p>
      </header>

      <div id="banner">
        <span id="logo"></span>

        <a href="https://github.com/atmb4u/marlin" class="button fork"><strong>View On GitHub</strong></a>
        <div class="downloads">
          <span>Downloads:</span>
          <ul>
            <li><a href="https://github.com/atmb4u/marlin/zipball/master" class="button">ZIP</a></li>
            <li><a href="https://github.com/atmb4u/marlin/tarball/master" class="button">TAR</a></li>
          </ul>
        </div>
      </div><!-- end banner -->

    <div class="wrapper">
      <nav>
        <ul></ul>
      </nav>
      <section>
        <p><img src="https://github.com/atmb4u/marlin/blob/master/marlin/static/marlin.jpg?raw=true" alt="Marlin"></p>

<h1>
<a name="marlin" class="anchor" href="#marlin"><span class="octicon octicon-link"></span></a>Marlin</h1>

<h4>
<a name="a-fast-frill-free-rest-api-with-zero-setup-time-is-too-interesting" class="anchor" href="#a-fast-frill-free-rest-api-with-zero-setup-time-is-too-interesting"><span class="octicon octicon-link"></span></a>a fast, frill-free REST API with ZERO setup time is too interesting.</h4>

<h2>
<a name="quick-start-guide" class="anchor" href="#quick-start-guide"><span class="octicon octicon-link"></span></a>Quick Start Guide</h2>

<div class="highlight highlight-bash"><pre>
pip install marlin  <span class="c"># install marlin to the python environment.</span>

marlin-server start  <span class="c"># start marlin server - port: 5000</span>

</pre></div>

<h2>
<a name="detailed-installation-in-ubuntu" class="anchor" href="#detailed-installation-in-ubuntu"><span class="octicon octicon-link"></span></a>Detailed Installation in Ubuntu</h2>

<ul>
<li>redis-server</li>
</ul><div class="highlight highlight-bash"><pre>sudo apt-get install redis-server
</pre></div>

<ul>
<li>create virtualenv</li>
</ul><div class="highlight highlight-bash"><pre>sudo apt-get install python-pip
sudo pip install virtualenv
virtualenv marlin-env
<span class="nb">source </span>marlin-env/bin/activate
</pre></div>

<ul>
<li>requests, ujson, flask, python-daemon</li>
</ul><div class="highlight highlight-bash"><pre>pip install flask requests ujson python-daemon
</pre></div>

<ul>
<li>install marlin</li>
</ul><div class="highlight highlight-bash"><pre>pip install marlin  <span class="c"># install marlin to the python environment.</span>

</pre></div>

<h2>
<a name="managing-server" class="anchor" href="#managing-server"><span class="octicon octicon-link"></span></a>Managing Server</h2>

<div class="highlight highlight-bash"><pre>marlin-server start  <span class="c"># starts server with default conf on port 5000</span>

marlin-server stop  <span class="c"># stops the server</span>

marlin-server restart  <span class="c"># restart the server</span>

marlin-server live  <span class="c"># starts a server on DEBUG mode</span>
</pre></div>

<h2>
<a name="request-methods" class="anchor" href="#request-methods"><span class="octicon octicon-link"></span></a>Request Methods</h2>

<table>
<thead><tr>
<th>METHOD</th>
<th align="center">URL</th>
<th align="center">RESPONSE</th>
<th align="center">DESCRIPTION</th>
</tr></thead>
<tbody>
<tr>
<td>GET</td>
<td align="center">/api/v1//?start=1&amp;end=10</td>
<td align="center">[data] 1-10</td>
<td align="center">returns the 1-10 elements in the </td>
</tr>
<tr>
<td>GET</td>
<td align="center">/api/v1//1</td>
<td align="center">data item</td>
<td align="center">returns the element with id 1</td>
</tr>
<tr>
<td>GET</td>
<td align="center">/ping/</td>
<td align="center">200/500</td>
<td align="center">check if service is up and connected</td>
</tr>
<tr>
<td>POST</td>
<td align="center">/api/v1//</td>
<td align="center">[data]</td>
<td align="center">adds data to the model</td>
</tr>
<tr>
<td>PUT</td>
<td align="center">/api/v1//1/</td>
<td align="center">[data]</td>
<td align="center">edit data</td>
</tr>
<tr>
<td>DELETE</td>
<td align="center">/api/v1//1</td>
<td align="center">200</td>
<td align="center">delete the data item</td>
</tr>
<tr>
<td>DELETE</td>
<td align="center">/api/v1//</td>
<td align="center">-</td>
<td align="center">delete complete data in model</td>
</tr>
<tr>
<td>DELETE</td>
<td align="center">/api/v1//&amp;force=1</td>
<td align="center">-</td>
<td align="center">delete and reset model (starts with id=1</td>
</tr>
</tbody>
</table><h2>
<a name="server-configuration" class="anchor" href="#server-configuration"><span class="octicon octicon-link"></span></a>Server Configuration</h2>

<p><strong>marlin.config</strong></p>

<p>For custom configuration, just create a <strong>marlin.config</strong> on the directory from where you are starting marlin-server.</p>

<pre><code>
[SERVER]
DEBUG = True
PID_FILE = /tmp/marlin.pid
LOG_FILE = /tmp/marlin.log
SERVER_PORT = 5000

[REDIS]
REDIS_SERVER = localhost
REDIS_PORT = 6379
API_PREFIX = /api/

[APP]
APP_NAME = marlin
</code></pre>

<h2>
<a name="custom-urls-and-functions" class="anchor" href="#custom-urls-and-functions"><span class="octicon octicon-link"></span></a>Custom Urls and Functions</h2>

<p>Always, a basic REST API is just a scaffolding for the application, and custom defined urls and functions make it beautiful. As marlin is more focused on performance, it is designed for flexibility as well.</p>

<p>It is pretty simple to create custom functions in Marlin.</p>

<p>Just place <code>marlin_function.py</code> in the present working directory (pwd), with custom routes and custom responses.</p>

<div class="highlight highlight-python"><pre><span class="c"># marlin_functions.py</span>
<span class="kn">from</span> <span class="nn">marlin</span> <span class="kn">import</span> <span class="n">app</span>


<span class="nd">@app.route</span><span class="p">(</span><span class="s">"/example/"</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="s">"Simple Custom Response"</span><span class="p">)</span>
</pre></div>

<p>or a more complex example.</p>

<h3>
<a name="to-get-a-custom-element-based-on-a-user-id" class="anchor" href="#to-get-a-custom-element-based-on-a-user-id"><span class="octicon octicon-link"></span></a>To get a custom element based on a user id</h3>

<div class="highlight highlight-python"><pre><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">marlin</span> <span class="kn">import</span> <span class="n">app</span><span class="p">,</span> <span class="n">RedisDatabaseManager</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Response</span><span class="p">,</span> <span class="n">request</span>


<span class="nd">@app.route</span><span class="p">(</span><span class="s">"/simple_get/&lt;model&gt;"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">custom_get</span><span class="p">(</span><span class="n">model</span><span class="p">):</span>
    <span class="n">rdm</span> <span class="o">=</span> <span class="n">RedisDatabaseManager</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">model</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="s">'v1'</span><span class="p">)</span>
    <span class="n">user_id</span> <span class="o">=</span> <span class="mi">127</span>
    <span class="k">if</span> <span class="n">rdm</span><span class="p">:</span>
        <span class="n">rdm</span><span class="o">.</span><span class="n">manipulate_data</span><span class="p">()</span>
        <span class="n">rdm</span><span class="o">.</span><span class="n">get_from_redis</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>  <span class="c"># get data for the specific user id</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">"status"</span><span class="p">:</span> <span class="s">"Something is not right"</span><span class="p">})</span>
    <span class="k">if</span> <span class="n">rdm</span><span class="o">.</span><span class="n">status</span> <span class="ow">and</span> <span class="n">rdm</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="n">rdm</span><span class="o">.</span><span class="n">string_data</span><span class="p">,</span> <span class="n">content_type</span><span class="o">=</span><span class="s">'application/json; charset=utf-8'</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">rdm</span><span class="o">.</span><span class="n">status</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">'status'</span><span class="p">:</span> <span class="s">"No data Found"</span><span class="p">}),</span> <span class="n">content_type</span><span class="o">=</span><span class="s">'application/json; charset=utf-8'</span><span class="p">,</span>
                        <span class="n">status</span><span class="o">=</span><span class="mi">404</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">"status"</span><span class="p">:</span> <span class="s">"Something is not right"</span><span class="p">})</span>
</pre></div>

<p>A little more complicated Example</p>

<h3>
<a name="following-example-filter-all-the-objects-with-nameapple" class="anchor" href="#following-example-filter-all-the-objects-with-nameapple"><span class="octicon octicon-link"></span></a>Following example filter all the objects with <code>name=Apple</code>
</h3>

<div class="highlight highlight-python"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/&lt;model&gt;/'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">little_complicated</span><span class="p">(</span><span class="n">model</span><span class="p">):</span>
    <span class="n">custom_range_start</span> <span class="o">=</span> <span class="mi">10</span>
    <span class="n">custom_range_end</span> <span class="o">=</span> <span class="mi">70</span>
    <span class="n">error_response</span> <span class="o">=</span> <span class="n">Response</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span>
        <span class="p">{</span><span class="s">'status'</span><span class="p">:</span> <span class="s">"Some unknown error"</span><span class="p">}),</span>
        <span class="n">content_type</span><span class="o">=</span><span class="s">'application/json; charset=utf-8'</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span>
    <span class="n">rdm</span> <span class="o">=</span> <span class="n">RedisDatabaseManager</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">rdm</span><span class="p">:</span>
        <span class="n">rdm</span><span class="o">.</span><span class="n">manipulate_data</span><span class="p">()</span>
        <span class="n">rdm</span><span class="o">.</span><span class="n">get_many_from_redis</span><span class="p">(</span><span class="n">custom_range_start</span><span class="p">,</span> <span class="n">custom_range_end</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">error_response</span>
    <span class="k">if</span> <span class="n">rdm</span><span class="o">.</span><span class="n">status</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">rdm</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
            <span class="n">custom_query_set</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">datum</span> <span class="ow">in</span> <span class="n">rdm</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">datum</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"name"</span><span class="p">)</span> <span class="o">==</span> <span class="s">"Apple"</span><span class="p">:</span>
                    <span class="n">custom_query_set</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">datum</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">custom_query_set</span><span class="p">),</span> <span class="n">content_type</span><span class="o">=</span><span class="s">'application/json; charset=utf-8'</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">Response</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">'status'</span><span class="p">:</span> <span class="s">"No data Found"</span><span class="p">}),</span> <span class="n">content_type</span><span class="o">=</span><span class="s">'application/json; charset=utf-8'</span><span class="p">,</span>
                            <span class="n">status</span><span class="o">=</span><span class="mi">404</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">error_response</span>
</pre></div>
      </section>
      <footer>
        <p>Project maintained by <a href="https://github.com/atmb4u">atmb4u</a></p>
        <p><small>Hosted on GitHub Pages &mdash; Theme by <a href="https://twitter.com/michigangraham">mattgraham</a></small></p>
      </footer>
    </div>
    <!--[if !IE]><script>fixScale(document);</script><![endif]-->
              <script type="text/javascript">
            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
          </script>
          <script type="text/javascript">
            try {
              var pageTracker = _gat._getTracker("UA-50163949-1");
            pageTracker._trackPageview();
            } catch(err) {}
          </script>

  </body>
</html>